package dac

import "encoding/binary"

func InsertBuf(buf []byte, startidx int, val []byte) (newBuf []byte) {
	// 延长切片长度
	newBuf = append(buf, val...)

	// 把数据推后
	copy(newBuf[startidx+len(val):], newBuf[startidx:])

	// 插入新数据
	copy(newBuf[startidx:], val)
	return
}

func DeleteBuf(buf []byte, startidx, n int) (newBuf []byte) {
	j := startidx + n
	if j < len(buf) {
		newBuf = append(buf[:startidx], buf[j:]...)
	} else {
		newBuf = buf[:startidx]
	}
	return
}

func bytes_grow(buf []byte, n int) []byte {
	newBuf := make([]byte, len(buf), 2*cap(buf)+n)
	copy(newBuf, buf)
	return newBuf
}

// Grow grows b's capacity, if necessary, to guarantee space for
// another n bytes. After Grow(n), at least n bytes can be written to b
// without another allocation. If n is negative, Grow panics.
func BytesCheckGrow(buf []byte, n int) []byte {
	if n < 0 {
		panic("utils.BytesBuilder.Grow: negative count")
	}
	if cap(buf)-len(buf) < n {
		return bytes_grow(buf, n)
	}
	return buf
}

func BytesCheckSize(buf []byte, start, l int) []byte {
	if start < 0 {
		for i := 0; i < l; i++ {
			buf = append(buf, 0)
		}
		return buf
	}
	n := (start + l) - len(buf)
	if n <= 0 {
		return buf
	}

	for i := 0; i < n; i++ {
		buf = append(buf, 0)
	}
	return buf
}

func BytesAppendUInt64_LE(buf []byte, v uint64) []byte {
	newBuf := BytesCheckGrow(buf, 8)
	newBuf = BytesCheckSize(newBuf, -1, 8)
	binary.LittleEndian.PutUint64(newBuf[len(newBuf)-8:], v)
	return newBuf
}

func BytesAppendUInt32_LE(buf []byte, v uint32) []byte {
	newBuf := BytesCheckGrow(buf, 4)
	newBuf = BytesCheckSize(newBuf, -1, 4)
	binary.LittleEndian.PutUint32(newBuf[len(newBuf)-4:], v)
	return newBuf
}
